package com.backend.modules.statistics.service.impl;

import com.backend.common.utils.RedisUtils;
import com.backend.common.utils.SecurityUtils;
import com.backend.modules.statistics.service.StatisticsService;
import com.backend.modules.statistics.vo.AdminStatisticsVO;
import com.backend.modules.statistics.vo.StudentStatisticsVO.ClassRanking;
import com.backend.modules.statistics.vo.StudentStatisticsVO.SubmissionHistory;
import com.backend.modules.statistics.vo.StudentStatisticsVO.TaskOverview;
import com.backend.modules.statistics.vo.TeacherStatisticsVO;
import com.backend.modules.statistics.vo.StudentStatisticsVO;
import com.backend.modules.system.repository.SysUserRepository;
import com.backend.modules.task.repository.TaskRepository;
import com.backend.modules.task.repository.TaskSubmissionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class StatisticsServiceImpl implements StatisticsService {

    private final RedisUtils redisUtils;
    private final SysUserRepository userRepository;
    private final TaskRepository taskRepository;
    private final TaskSubmissionRepository submissionRepository;
    
    private static final String ADMIN_STATS_KEY = "stats:admin:%s:%s:%s";
    private static final long CACHE_TIMEOUT = 30; // 缓存30分钟
    
    @Override
    public AdminStatisticsVO getAdminStatistics(Long gradeId, Long majorId, Long classId) {
        // 生成缓存key
        String cacheKey = String.format(ADMIN_STATS_KEY, gradeId, majorId, classId);
        
        // 尝试从缓存获取
//        AdminStatisticsVO stats = redisUtils.get(cacheKey);
//        if (stats != null) {
//            return stats;
//        }
//
        // 缓存不存在，计算统计数据
        AdminStatisticsVO  stats = calculateAdminStatistics(gradeId, majorId, classId);
        
        // 存入缓存
        redisUtils.set(cacheKey, stats, CACHE_TIMEOUT, TimeUnit.MINUTES);
        
        return stats;
    }
    
    private AdminStatisticsVO calculateAdminStatistics(Long gradeId, Long majorId, Long classId) {
        AdminStatisticsVO vo = new AdminStatisticsVO();
        
        // 计算总览数据
        AdminStatisticsVO.Overview overview = new AdminStatisticsVO.Overview();
        overview.setTotalTasks(taskRepository.countAll());
        overview.setTotalSubmissions(submissionRepository.countAll());
        overview.setTotalStudents(userRepository.countByUserType(3));
        overview.setTotalTeachers(userRepository.countByUserType(2));
        overview.setAverageSubmitRate(calculateAverageSubmitRate());
        vo.setOverview(overview);
        
        // 计算提交率排名
        vo.setSubmitRateRanking(calculateSubmitRateRanking(gradeId, majorId, classId));
        
        // 计算近期提交趋势
        vo.setSubmitTrend(calculateSubmitTrend());
        
        return vo;
    }
    
    private Double calculateAverageSubmitRate() {
        // 实现计算平均提交率的逻辑
        return submissionRepository.calculateAverageSubmitRate();
    }
    
    private List<AdminStatisticsVO.DepartmentSubmitRate> calculateSubmitRateRanking(
            Long gradeId, Long majorId, Long classId) {
        // 从数据库获取部门提交率排名
        List<AdminStatisticsVO.DepartmentSubmitRate> ranking = 
            submissionRepository.calculateDepartmentSubmitRates(gradeId, majorId, classId);
        
        // 如果没有数据，返回空列表
        if (ranking == null || ranking.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 处理提交率为null的情况
        ranking.forEach(dept -> {
            if (dept.getSubmitRate() == null) {
                dept.setSubmitRate(0.0);
            }
        });
        
        return ranking;
    }
    
    private List<AdminStatisticsVO.DailySubmitTrend> calculateSubmitTrend() {
        // 实现计算近期提交趋势的逻辑
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        List<AdminStatisticsVO.DailySubmitTrend> trends = new ArrayList<>();
        
        // 获取最近7天的数据
        for (int i = 6; i >= 0; i--) {
            LocalDateTime date = now.minusDays(i);
            AdminStatisticsVO.DailySubmitTrend trend = new AdminStatisticsVO.DailySubmitTrend();
            trend.setDate(date.format(formatter));
            trend.setSubmitCount(submissionRepository.countBySubmitDate(date));
            trend.setOverdueCount(submissionRepository.countOverdueBySubmitDate(date));
            trends.add(trend);
        }
        
        return trends;
    }

    @Override
    public TeacherStatisticsVO getTeacherStatistics(Long classId) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        String cacheKey = String.format("stats:teacher:%s:%s", teacherId, classId);
        
        // 尝试从缓存获取
//        TeacherStatisticsVO stats = redisUtils.get(cacheKey);
//        if (stats != null) {
//            return stats;
//        }
//
        // 计算统计数据
        TeacherStatisticsVO stats = calculateTeacherStatistics(teacherId, classId);
        
        // 存入缓存
        redisUtils.set(cacheKey, stats, CACHE_TIMEOUT, TimeUnit.MINUTES);
        
        return stats;
    }

    private TeacherStatisticsVO calculateTeacherStatistics(Long teacherId, Long classId) {
        TeacherStatisticsVO vo = new TeacherStatisticsVO();
        
        // 计算总览数据
        TeacherStatisticsVO.Overview overview = new TeacherStatisticsVO.Overview();
        overview.setTotalTasks(submissionRepository.countTeacherTasks(teacherId));
        overview.setOngoingTasks(submissionRepository.countTeacherOngoingTasks(teacherId));
        overview.setTotalSubmissions(submissionRepository.countTeacherSubmissions(teacherId));
        overview.setPendingReviews(submissionRepository.countTeacherPendingReviews(teacherId));
        overview.setAverageSubmitRate(submissionRepository.calculateTeacherAverageSubmitRate(teacherId));
        vo.setOverview(overview);
        
        // 计算班级提交情况
        vo.setClassSubmitStatus(submissionRepository.calculateClassSubmitStatus(teacherId, classId));
        
        // 计算近期提交趋势
        vo.setSubmitTrend(calculateTeacherSubmitTrend(teacherId));
        
        return vo;
    }

    private List<TeacherStatisticsVO.DailySubmitTrend> calculateTeacherSubmitTrend(Long teacherId) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        List<TeacherStatisticsVO.DailySubmitTrend> trends = new ArrayList<>();
        
        // 获取最近7天的数据
        for (int i = 6; i >= 0; i--) {
            LocalDateTime date = now.minusDays(i);
            TeacherStatisticsVO.DailySubmitTrend trend = new TeacherStatisticsVO.DailySubmitTrend();
            trend.setDate(date.format(formatter));
            trend.setSubmitCount(submissionRepository.countBySubmitDateAndTeacher(date, teacherId));
            trend.setOverdueCount(submissionRepository.countOverdueBySubmitDateAndTeacher(date, teacherId));
            trends.add(trend);
        }
        
        return trends;
    }



    @Override
    public StudentStatisticsVO getStudentStatistics() {
        Long studentId = SecurityUtils.getCurrentUserId();
        String cacheKey = String.format("stats:student:%s", studentId);
        
        // 尝试从缓存获取
//        StudentStatisticsVO stats = redisUtils.get(cacheKey);
//        if (stats != null) {
//            return stats;
//        }
        
        // 计算统计数据
        StudentStatisticsVO stats = calculateStudentStatistics(studentId);
        
        // 存入缓存
        redisUtils.set(cacheKey, stats, CACHE_TIMEOUT, TimeUnit.MINUTES);
        
        return stats;
    }

    private StudentStatisticsVO calculateStudentStatistics(Long studentId) {
        StudentStatisticsVO vo = new StudentStatisticsVO();
        
        // 计算任务概览
        TaskOverview taskOverview = new TaskOverview();
        taskOverview.setOngoingTasks(submissionRepository.countStudentOngoingTasks(studentId)); // 计算进行中任务
        taskOverview.setCompletedTasks(submissionRepository.countStudentCompletedTasks(studentId)); // 计算已完成任务
        taskOverview.setOverdueTasks(submissionRepository.countStudentOverdueTasks(studentId)); // 计算逾期任务
        taskOverview.setSubmitRate(submissionRepository.calculateStudentSubmitRate(studentId)); // 计算提交率
        vo.setTaskOverview(taskOverview);
        
        // 获取提交历史
        vo.setSubmissionHistory(submissionRepository.getStudentSubmissionHistory(studentId));
        
        // 获取班级排名
        vo.setClassRanking(getStudentClassRanking(studentId));
        
        return vo;
    }

    private StudentStatisticsVO.ClassRanking getStudentClassRanking(Long studentId) {
        Integer totalStudents = submissionRepository.getClassTotalStudents(studentId);
        Integer currentRank = submissionRepository.getCurrentRank(studentId);
        Double submitRate = submissionRepository.getStudentSubmitRate(studentId);
        
        // 获取班级所有学生的提交率
        List<Double> classSubmitRates = submissionRepository.getClassAverageSubmitRate(studentId);
        Double classAverageRate = classSubmitRates.stream()
            .mapToDouble(Double::doubleValue)
            .average()
            .orElse(0.0);
        
        // 添加空值处理
        totalStudents = totalStudents != null ? totalStudents : 0;
        currentRank = currentRank != null ? currentRank : 1;
        submitRate = submitRate != null ? submitRate : 0.0;
        
        return new StudentStatisticsVO.ClassRanking(
            totalStudents.longValue(),
            currentRank.longValue(),
            submitRate,
            classAverageRate
        );
    }
} 